(define-syntax and
  (lambda (exp env)
    (if (null? (syn-cdr exp))
        (syntax-quote #t)
        (list (syntax-quote if)
              (syn-car (syn-cdr exp))
              (cons (syn-car exp)
                    (syn-cdr (syn-cdr exp)))
              (syntax-quote #f)))))

(define-syntax or
  (lambda (exp env)
    (list (syntax-quote let)
	  (list
	   (list (syntax-quote tmp)
		 (syn-car (syn-cdr exp))))
	  (list (syntax-quote if)
		(syntax-quote tmp)
		(syntax-quote tmp)
		(syn-car (syn-cdr (syn-cdr exp)))))))

(define-syntax quasiquote
  (lambda (exp env)
    ;;
    ;; `,x      --> x
    ;; `x `()   --> 'x '()
    ;; `(p . q) --> (`p . `q)
    ;;
    (let ((unquote? (lambda (exp)
		      (and (pair? exp)
			   (syx-id? (syn-car exp))
			   (identifier-equal? env
					      (syntax-quote unquote)
					      (syn-car exp))))))
      (let ((d (syn-car (syn-cdr exp))))
	(if (unquote? d)
	    (syn-car (syn-cdr d))
	    (if (or (syx-id? d) (null? d))
		(list (syntax-quote quote) d)
		(if (pair? d)
		    (list (syntax-quote cons)
			  (list (syntax-quote quasiquote) (syn-car d))
			  (list (syntax-quote quasiquote) (syn-cdr d)))
		    (error "bad syntax in quasiquote" d))))))))

(define t1 (print (let ((x 3)) `(hello ,x world))))
